const { sequelize, DataTypes } = require('../config/database');
const moment = require('moment');

const Activity = sequelize.define('Activity', {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true
  },

  // Basic information
  title: {
    type: DataTypes.STRING(100),
    allowNull: false,
    validate: {
      notEmpty: true,
      len: [1, 100]
    }
  },

  description: {
    type: DataTypes.TEXT,
    allowNull: false,
    validate: {
      notEmpty: true,
      len: [1, 1000]
    }
  },

  type: {
    type: DataTypes.ENUM('music', 'sports', 'food', 'gaming', 'movie', 'travel', 'study', 'party', 'other'),
    defaultValue: 'other'
  },

  // Media
  mainImage: {
    type: DataTypes.STRING,
    allowNull: false,
    defaultValue: 'https://picsum.photos/400/300?random=1'
  },

  images: {
    type: DataTypes.JSON
  },

  // Time and duration
  startTime: {
    type: DataTypes.DATE,
    allowNull: false
  },

  endTime: {
    type: DataTypes.DATE,
    allowNull: false,
    validate: {
      isAfterStart(value) {
        if (value <= this.startTime) {
          throw new Error('End time must be after start time');
        }
      }
    }
  },

  // Location (JSON)
  location: {
    type: DataTypes.JSON,
    allowNull: false,
    validate: {
      isValidLocation(value) {
        if (!value.name || !value.address || !value.coordinates) {
          throw new Error('Location must include name, address, and coordinates');
        }
      }
    }
  },

  // Participation settings
  maxParticipants: {
    type: DataTypes.INTEGER,
    allowNull: false,
    validate: {
      min: 2,
      max: 1000
    }
  },

  minParticipants: {
    type: DataTypes.INTEGER,
    defaultValue: 2,
    validate: {
      min: 1,
      isLessThanMax(value) {
        if (value >= this.maxParticipants) {
          throw new Error('Minimum participants must be less than maximum participants');
        }
      }
    }
  },

  currentParticipants: {
    type: DataTypes.INTEGER,
    defaultValue: 1,
    validate: {
      min: 0
    }
  },

  // 创建者ID
  creatorId: {
    type: DataTypes.INTEGER,
    allowNull: false,
    references: {
      model: 'users',
      key: 'id'
    }
  },

  // 价格
  price: {
    type: DataTypes.DECIMAL(10, 2),
    defaultValue: 0,
    validate: {
      min: 0
    }
  },
  // Activity status
  status: {
    type: DataTypes.ENUM('draft', 'published', 'cancelled', 'ongoing', 'completed', 'expired'),
    defaultValue: 'published'
  },

  // Requirements and restrictions (JSON)
  requirements: {
    type: DataTypes.JSON
  },

  // Average rating
  averageRating: {
    type: DataTypes.DECIMAL(3, 2),
    defaultValue: 0,
    validate: {
      min: 0,
      max: 5
    }
  },

  // Tags for search and categorization (JSON)
  tags: {
    type: DataTypes.JSON
  },

  // Visibility and privacy
  visibility: {
    type: DataTypes.ENUM('public', 'friends-only', 'private'),
    defaultValue: 'public'
  },

  // Timestamps
  publishedAt: {
    type: DataTypes.DATE
  },

  cancelledAt: {
    type: DataTypes.DATE
  },

  completedAt: {
    type: DataTypes.DATE
  }

}, {
  tableName: 'parkpart_activities',  // 修改表名
  timestamps: true,
  paranoid: true,
  indexes: [
    { fields: ['creatorId'] },
    { fields: ['startTime'] },
    { fields: ['endTime'] },
    { fields: ['status'] },
    { fields: ['type'] },
    { fields: ['createdAt'] }
  ]
});

// 关联表定义
Activity.associate = (models) => {
  // 活动创建者
  Activity.belongsTo(models.User, {
    foreignKey: 'creatorId',
    as: 'creator'
  });

  // 活动参与者
  Activity.belongsToMany(models.User, {
    through: 'parkpart_activity_participants',  // 修改关联表名
    as: 'participants',
    foreignKey: 'activityId',
    otherKey: 'userId'
  });

  // 活动点赞
  Activity.belongsToMany(models.User, {
    through: 'parkpart_activity_likes',  // 修改关联表名
    as: 'likes',
    foreignKey: 'activityId',
    otherKey: 'userId'
  });

  // 活动评论
  Activity.hasMany(models.Comment, {
    foreignKey: 'activityId',
    as: 'comments'
  });

  // 活动评分
  Activity.hasMany(models.ActivityRating, {
    foreignKey: 'activityId',
    as: 'ratings'
  });
};

// 实例方法
Activity.prototype.isFull = function () {
    return this.currentParticipants >= this.maxParticipants;
  };
 
  Activity.prototype.isOngoing = function () {
    const now = new Date();
    return now >= this.startTime && (this.endTime ? now < this.endTime : true);
  };

Activity.prototype.isUpcoming = function () {
  return new Date() < this.startTime && this.status === 'published';
};

Activity.prototype.isExpired = function () {
  return this.endTime && new Date() > this.endTime;
};

Activity.prototype.spotsAvailable = function () {
  return Math.max(0, this.maxParticipants - this.currentParticipants);
};

Activity.prototype.duration = function () {
  const duration = moment.duration(moment(this.endTime).diff(moment(this.startTime)));
  return {
    hours: duration.hours(),
    minutes: duration.minutes(),
    totalMinutes: duration.asMinutes()
  };
};

Activity.prototype.isUserParticipant = function (userId) {
  return this.participants ? this.participants.some(p => p.id === userId) : false;
};

Activity.prototype.isCreator = function (userId) {
  return this.creatorId === userId;
};

Activity.prototype.canJoin = function (userId) {
  const now = new Date();
  
  // 检查活动状态、是否满员、是否已开始
  if (this.status !== 'published') {
    console.log(`canJoin false: 活动状态不是 published，当前状态: ${this.status}`);
    return false;
  }
  
  if (this.isFull()) {
    console.log(`canJoin false: 活动已满员，当前参与者: ${this.currentParticipants}/${this.maxParticipants}`);
    return false;
  }
  
  if (this.endTime && now >= this.endTime) {
    console.log(`canJoin false: 活动已结束，当前时间: ${now}, 结束时间: ${this.endTime}`);
    return false;
  }
  
  // 检查用户是否已经是参与者
  if (!this.participants || this.participants.length === 0) {
    console.log(`canJoin true: 没有参与者或参与者列表为空`);
    return true;
  }
  
  const participant = this.participants.find(p => p.id === userId);
  
  // 如果用户不是参与者，可以加入
  if (!participant) {
    console.log(`canJoin true: 用户 ${userId} 不是参与者`);
    return true;
  }
  
  // 如果用户是参与者，检查状态
  const participantStatus = participant.parkpart_activity_participants ? 
    participant.parkpart_activity_participants.status : 'approved';
  
  console.log(`canJoin 检查: 用户 ${userId} 是参与者，状态: ${participantStatus}`);
  
  // 只有状态为 'rejected' 或 'cancelled' 的用户才能重新申请
  // pending状态的用户不能重复申请
  const canReapply = participantStatus === 'rejected' || participantStatus === 'cancelled';
  console.log(`canJoin 结果: ${canReapply}`);
  return canReapply;
};

Activity.prototype.canLeave = async function (userId) {
  const now = new Date();
  console.log(`canLeave 检查: 用户 ${userId}, 活动ID ${this.id}`);
  
  // 检查活动状态
  if (this.status === 'completed' || this.status === 'cancelled') {
    console.log(`canLeave false: 活动状态为 ${this.status}`);
    return false;
  }
  
  // 检查活动是否已结束
  if (this.endTime && now >= this.endTime) {
    console.log(`canLeave false: 活动已结束，当前时间: ${now}, 结束时间: ${this.endTime}`);
    return false;
  }
  
  // 检查用户是否是创建者
  if (this.creatorId === userId) {
    console.log(`canLeave false: 用户 ${userId} 是活动创建者`);
    return false;
  }
  
  // 使用关联查询检查用户是否是参与者
  const { sequelize } = require('../config/database');
  const [participant] = await sequelize.query(`
    SELECT status FROM parkpart_activity_participants 
    WHERE activityId = :activityId AND userId = :userId
  `, {
    replacements: { activityId: this.id, userId },
    type: sequelize.QueryTypes.SELECT
  });
  
  // 如果用户不是参与者，不能离开
  if (!participant) {
    console.log(`canLeave false: 用户 ${userId} 不是参与者`);
    return false;
  }
  
  // 如果用户是参与者，检查状态
  const participantStatus = participant.status || 'approved';
  
  console.log(`canLeave 检查: 用户 ${userId} 是参与者，状态: ${participantStatus}`);
  
  // 只有状态为 'approved' 或 'pending' 的用户才能离开
  // pending状态的用户可以取消申请
  const canLeave = participantStatus === 'approved' || participantStatus === 'pending';
  console.log(`canLeave 结果: ${canLeave}`);
  return canLeave;
};
Activity.prototype.isLikedByUser = function (userId) {
  return this.likes ? this.likes.some(like => like.id === userId) : false;
};

Activity.prototype.toJSON = function () {
  const values = Object.assign({}, this.get());
  // 移除敏感或不必要的字段
  delete values.ratings;
  return values;
};

// 钩子函数
Activity.beforeCreate(async (activity) => {
  // 设置默认值
  if (!activity.images) activity.images = [];
  if (!activity.requirements) activity.requirements = {
    ageRange: {},
    genderRestriction: 'none',
    cost: 0,
    currency: 'CNY',
    bringItems: [],
    skills: []
  };
  if (!activity.tags) activity.tags = [];

  if (activity.status === 'published') {
    activity.publishedAt = new Date();
  }
});

Activity.beforeUpdate(async (activity) => {
  // 确保JSON字段有值
  if (!activity.images) activity.images = [];
  if (!activity.requirements) activity.requirements = {
    ageRange: {},
    genderRestriction: 'none',
    cost: 0,
    currency: 'CNY',
    bringItems: [],
    skills: []
  };
  if (!activity.tags) activity.tags = [];

  if (activity.changed('status') && activity.status === 'published' && !activity.publishedAt) {
    activity.publishedAt = new Date();
  }
});

module.exports = Activity;